﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Diagnostics;
using System.IO;
using System.Web.Hosting;
using JJServices.FileService.Interface;
using Microsoft.Practices.ServiceLocation;
using JJServices.ImageCollectionService.Interface;
using JJRepositories.ImageCollectionRepository.Concreate;
using JJCore.EntityProviders;
using System.Security.Principal;
using JJServices.ApplicationService.Interface;
using JJCore.Enum;

namespace jamie_jonesAdmin
{
    /// <summary>
    /// Summary description for $codebehindclassname$
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class HttpUploadHandler : IHttpHandler
    {

        private HttpContext _httpContext;
        private string _tempExtension = "_temp";
        private string _fileName;
        private Dictionary<string, string> _parameters;
        private bool _lastChunk;
        private bool _firstChunk;
        private long _startByte;

        private IFileService fileService;
        private IImageCollectionService imageCollectionService;
        private IApplicationService applicationService;

        StreamWriter _debugFileStreamWriter;
        TextWriterTraceListener _debugListener;

        public HttpUploadHandler()
        {
            fileService = ServiceLocator.Current.GetInstance<IFileService>();
            imageCollectionService = ServiceLocator.Current.GetInstance<IImageCollectionService>();
            applicationService = ServiceLocator.Current.GetInstance<IApplicationService>();

            fileService.ApplicationPath = @HostingEnvironment.ApplicationPhysicalPath;
        }

        /// <summary>
        /// Start method
        /// </summary>
        /// <param name="context"></param>
        public void ProcessRequest(HttpContext context)
        {
            _httpContext = context;

            if (context.Request.InputStream.Length == 0)
                throw new ArgumentException("No file input");

            try
            {
                //StartDebugListener();

                GetQueryStringParameters();

                string uploadFolder = GetUploadFolder();
                string tempFileName = _fileName + _tempExtension;

                //Is it the first chunk? Prepare by deleting any existing files with the same name
                if (_firstChunk)
                {
                    if (!fileService.FolderExists(uploadFolder))
                        fileService.CreateFolder(uploadFolder);

                    Debug.WriteLine("First chunk arrived at webservice");

                    fileService.DeleteFile(uploadFolder + "/" + tempFileName);
                    fileService.DeleteFile(uploadFolder + "/" + _fileName);

                }

                //Write the file
                Debug.WriteLine(string.Format("Write data to disk FOLDER: {0}", uploadFolder));

                fileService.AppendFile(context.Request.InputStream, uploadFolder + "/" + tempFileName);

                Debug.WriteLine("Write data to disk SUCCESS");

                //Is it the last chunk? Then finish up...
                if (_lastChunk)
                {
                    Debug.WriteLine("Last chunk arrived");

                    fileService.MoveFile(uploadFolder + "/" + tempFileName,uploadFolder + "/" + _fileName);

                    //Finish stuff....
                    FinishedFileUpload(_fileName, _parameters);
                }

            }
            catch (Exception e)
            {
                Debug.WriteLine(e.ToString());

                throw;
            }
            finally
            {
                //StopDebugListener();
            }

        }

        /// <summary>
        /// Get the querystring parameters
        /// </summary>
        private void GetQueryStringParameters()
        {
            _fileName = _httpContext.Request.QueryString["file"];
            _lastChunk = string.IsNullOrEmpty(_httpContext.Request.QueryString["last"]) ? true : bool.Parse(_httpContext.Request.QueryString["last"]);
            _firstChunk = string.IsNullOrEmpty(_httpContext.Request.QueryString["first"]) ? true : bool.Parse(_httpContext.Request.QueryString["first"]);
            _startByte = string.IsNullOrEmpty(_httpContext.Request.QueryString["offset"]) ? 0 : long.Parse(_httpContext.Request.QueryString["offset"]); ;

            string tempParams = _httpContext.Request.QueryString["param"];
            _parameters = new Dictionary<string, string>();
            string[] paramArray = tempParams.Split('-');
        
            foreach(string param in paramArray)
            {
                string[] value = param.Split('_');
            
                _parameters.Add(value[0],value[1]);
            }
        }


        /// <summary>
        /// Do your own stuff here when the file is finished uploading
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="parameters"></param>
        protected virtual void FinishedFileUpload(string fileName, Dictionary<string,string> parameters)
        {

        }


        protected virtual string GetUploadFolder()
        {
            string folder = System.Configuration.ConfigurationSettings.AppSettings["UploadFolder"];

            if (string.IsNullOrEmpty(folder))
                folder = "Upload";

            folder = folder + "/" + _parameters.FirstOrDefault(d => d.Key == "name").Value;

            return folder;
        }


        /// <summary>
        /// Write debug output to a textfile in debug mode
        /// </summary>
        [Conditional("DEBUG")]
        private void StartDebugListener()
        {
            try
            {
                _debugFileStreamWriter = System.IO.File.AppendText("debug.txt");
                _debugListener = new TextWriterTraceListener(_debugFileStreamWriter);
                Debug.Listeners.Add(_debugListener);
            }
            catch
            {
            }
        }

        /// <summary>
        /// Clean up the debug listener
        /// </summary>
        [Conditional("DEBUG")]
        private void StopDebugListener()
        {
            try
            {
                Debug.Flush();
                _debugFileStreamWriter.Close();
                Debug.Listeners.Remove(_debugListener);
            }
            catch
            {
            }
        }


        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
